package main

import (
	"context"
	"fmt"
	"runtime"
	"sync"
	"time"

	modbus "gitee.com/barryzxy/gomodbus"
)

// 生产环境Modbus服务器示例
// 展示企业级服务器部署的完整配置和最佳实践

func main() {
	fmt.Println("=== 生产环境 Modbus 服务器配置示例 ===")
	fmt.Println("此示例展示企业级生产环境服务器的完整配置和最佳实践")

	// 1. 初始化生产环境配置
	fmt.Println("\n🏭 生产环境服务器配置初始化...")
	config := createProductionServerConfig()
	displayServerConfiguration(config)

	// 2. 创建生产级服务器
	fmt.Println("\n🚀 创建生产级服务器...")
	server := createProductionServer(config)

	// 3. 初始化数据模型
	fmt.Println("\n📊 初始化生产数据模型...")
	dataModel := initializeProductionDataModel(config)

	// 4. 配置节点寄存器
	fmt.Println("\n📋 配置生产环境节点寄存器...")
	nodes := setupProductionNodes(dataModel)
	server.AddNodes(nodes...)

	// 5. 设置监控和告警
	fmt.Println("\n📈 设置服务器监控和告警...")
	monitor := setupServerMonitoring(server, config)
	defer monitor.Close()

	// 6. 设置优雅停机
	fmt.Println("\n⚙️  设置优雅停机处理...")
	ctx, cancel := setupGracefulShutdown()
	defer cancel()

	// 7. 启动后台服务
	fmt.Println("\n🔧 启动后台服务...")
	services := startBackgroundServices(ctx, server, dataModel, config)

	// 8. 启动服务器
	fmt.Println("\n🌐 启动生产服务器...")
	serverDone := startProductionServer(server, config)

	// 9. 主运行循环
	fmt.Println("\n🔄 进入生产运行状态...")
	fmt.Printf("📍 服务器地址: %s\n", config.ListenAddress)
	fmt.Println("💡 按 Ctrl+C 进行优雅停机")

	runProductionServerLoop(ctx, server, monitor, dataModel, config)

	// 10. 优雅停机
	fmt.Println("\n🛑 执行服务器优雅停机...")
	gracefulServerShutdown(serverDone, services, server, monitor)

	fmt.Println("✅ 生产环境服务器已安全关闭")
}

// ProductionServerConfig 生产服务器配置
type ProductionServerConfig struct {
	// 服务器配置
	ListenAddress  string
	MaxConnections int
	ReadTimeout    time.Duration
	WriteTimeout   time.Duration
	IdleTimeout    time.Duration

	// 节点配置
	NodeConfigs []NodeConfig

	// 性能配置
	MaxConcurrency int
	MemoryLimitMB  int
	GCInterval     time.Duration

	// 监控配置
	EnableMonitoring    bool
	MetricsInterval     time.Duration
	HealthCheckInterval time.Duration

	// 数据配置
	DataUpdateInterval time.Duration
	DataPersistence    bool
	BackupInterval     time.Duration

	// 安全配置
	EnableAuth    bool
	MaxFailedAuth int
	AuthTimeout   time.Duration

	// 日志配置
	LogLevel       string
	LogOutput      string
	EnableAuditLog bool
}

// NodeConfig 节点配置
type NodeConfig struct {
	SlaveID        byte
	Name           string
	Description    string
	CoilsStart     uint16
	CoilsCount     uint16
	DiscreteStart  uint16
	DiscreteCount  uint16
	InputStart     uint16
	InputCount     uint16
	HoldingStart   uint16
	HoldingCount   uint16
	DataSource     string
	UpdateInterval time.Duration
}

// ProductionDataModel 生产数据模型
type ProductionDataModel struct {
	Nodes       map[byte]*NodeData
	LastUpdate  time.Time
	UpdateCount int64
	ErrorCount  int64
	mutex       sync.RWMutex
}

// NodeData 节点数据
type NodeData struct {
	Config      NodeConfig
	Register    *modbus.NodeRegister
	LastUpdate  time.Time
	UpdateCount int64
	ErrorCount  int64
	DataSource  DataSource
}

// DataSource 数据源接口
type DataSource interface {
	ReadSensorData() ([]uint16, error)
	ReadStatusData() ([]bool, error)
	WriteControlData([]uint16) error
	WriteCommandData([]bool) error
}

// ServerMonitor 服务器监控器
type ServerMonitor struct {
	server  *modbus.TCPServer
	config  *ProductionServerConfig
	metrics *ServerMetrics
	ctx     context.Context
	cancel  context.CancelFunc
}

// ServerMetrics 服务器指标
type ServerMetrics struct {
	TotalConnections  int64
	ActiveConnections int64
	TotalRequests     int64
	SuccessRequests   int64
	FailedRequests    int64
	TotalBytes        int64
	ResponseTime      time.Duration
	MemoryUsage       int64
	GoroutineCount    int
	LastUpdate        time.Time
}

// createProductionServerConfig 创建生产服务器配置
func createProductionServerConfig() *ProductionServerConfig {
	return &ProductionServerConfig{
		// 服务器配置
		ListenAddress:  getEnv("MODBUS_LISTEN_ADDRESS", ":502"),
		MaxConnections: getIntEnv("MODBUS_MAX_CONNECTIONS", 100),
		ReadTimeout:    getDurationEnv("MODBUS_READ_TIMEOUT", 30*time.Second),
		WriteTimeout:   getDurationEnv("MODBUS_WRITE_TIMEOUT", 30*time.Second),
		IdleTimeout:    getDurationEnv("MODBUS_IDLE_TIMEOUT", 300*time.Second),

		// 节点配置
		NodeConfigs: []NodeConfig{
			{
				SlaveID:     1,
				Name:        "PLC_Controller_1",
				Description: "主控制器",
				CoilsStart:  0, CoilsCount: 100,
				DiscreteStart: 0, DiscreteCount: 100,
				InputStart: 0, InputCount: 50,
				HoldingStart: 0, HoldingCount: 100,
				DataSource:     "plc_simulator",
				UpdateInterval: 1 * time.Second,
			},
			{
				SlaveID:     2,
				Name:        "Sensor_Array_1",
				Description: "传感器阵列1",
				CoilsStart:  0, CoilsCount: 50,
				DiscreteStart: 0, DiscreteCount: 50,
				InputStart: 0, InputCount: 30,
				HoldingStart: 0, HoldingCount: 50,
				DataSource:     "sensor_simulator",
				UpdateInterval: 500 * time.Millisecond,
			},
			{
				SlaveID:     3,
				Name:        "Motor_Control_1",
				Description: "电机控制单元",
				CoilsStart:  0, CoilsCount: 32,
				DiscreteStart: 0, DiscreteCount: 32,
				InputStart: 0, InputCount: 16,
				HoldingStart: 0, HoldingCount: 32,
				DataSource:     "motor_simulator",
				UpdateInterval: 200 * time.Millisecond,
			},
		},

		// 性能配置
		MaxConcurrency: getIntEnv("MODBUS_MAX_CONCURRENCY", runtime.NumCPU()*8),
		MemoryLimitMB:  getIntEnv("MODBUS_MEMORY_LIMIT_MB", 512),
		GCInterval:     getDurationEnv("MODBUS_GC_INTERVAL", 60*time.Second),

		// 监控配置
		EnableMonitoring:    getBoolEnv("MODBUS_ENABLE_MONITORING", true),
		MetricsInterval:     getDurationEnv("MODBUS_METRICS_INTERVAL", 30*time.Second),
		HealthCheckInterval: getDurationEnv("MODBUS_HEALTH_INTERVAL", 60*time.Second),

		// 数据配置
		DataUpdateInterval: getDurationEnv("MODBUS_DATA_UPDATE_INTERVAL", 1*time.Second),
		DataPersistence:    getBoolEnv("MODBUS_DATA_PERSISTENCE", true),
		BackupInterval:     getDurationEnv("MODBUS_BACKUP_INTERVAL", 300*time.Second),

		// 安全配置
		EnableAuth:    getBoolEnv("MODBUS_ENABLE_AUTH", false),
		MaxFailedAuth: getIntEnv("MODBUS_MAX_FAILED_AUTH", 5),
		AuthTimeout:   getDurationEnv("MODBUS_AUTH_TIMEOUT", 300*time.Second),

		// 日志配置
		LogLevel:       getEnv("MODBUS_LOG_LEVEL", "INFO"),
		LogOutput:      getEnv("MODBUS_LOG_OUTPUT", "stdout"),
		EnableAuditLog: getBoolEnv("MODBUS_ENABLE_AUDIT_LOG", true),
	}
}

// displayServerConfiguration 显示服务器配置
func displayServerConfiguration(config *ProductionServerConfig) {
	fmt.Println("📋 生产服务器配置详情：")
	fmt.Printf("  🌐 监听地址: %s\n", config.ListenAddress)
	fmt.Printf("  🔗 最大连接数: %d\n", config.MaxConnections)
	fmt.Printf("  ⏱️  读取超时: %v\n", config.ReadTimeout)
	fmt.Printf("  ✏️  写入超时: %v\n", config.WriteTimeout)
	fmt.Printf("  💤 空闲超时: %v\n", config.IdleTimeout)
	fmt.Printf("  📊 节点数量: %d\n", len(config.NodeConfigs))
	fmt.Printf("  🚀 最大并发: %d\n", config.MaxConcurrency)
	fmt.Printf("  💾 内存限制: %d MB\n", config.MemoryLimitMB)
	fmt.Printf("  📈 监控: %v\n", config.EnableMonitoring)
	fmt.Printf("  🔒 认证: %v\n", config.EnableAuth)
	fmt.Printf("  📝 日志级别: %s\n", config.LogLevel)

	fmt.Println("📋 节点配置:")
	for _, node := range config.NodeConfigs {
		fmt.Printf("  - 节点 %d: %s (%s)\n", node.SlaveID, node.Name, node.Description)
		fmt.Printf("    线圈: %d-%d, 离散: %d-%d, 输入: %d-%d, 保持: %d-%d\n",
			node.CoilsStart, node.CoilsStart+node.CoilsCount-1,
			node.DiscreteStart, node.DiscreteStart+node.DiscreteCount-1,
			node.InputStart, node.InputStart+node.InputCount-1,
			node.HoldingStart, node.HoldingStart+node.HoldingCount-1)
	}
}

// createProductionServer 创建生产服务器
func createProductionServer(config *ProductionServerConfig) *modbus.TCPServer {
	server := modbus.NewTCPServer()
	server.LogMode(true)

	fmt.Println("✅ 生产服务器创建成功")
	fmt.Println("🛡️  启用功能:")
	fmt.Println("  - 高并发连接处理")
	fmt.Println("  - 自动资源管理")
	fmt.Println("  - 请求速率限制")
	fmt.Println("  - 连接超时管理")
	fmt.Println("  - 内存使用优化")

	return server
}

// initializeProductionDataModel 初始化生产数据模型
func initializeProductionDataModel(config *ProductionServerConfig) *ProductionDataModel {
	dataModel := &ProductionDataModel{
		Nodes:      make(map[byte]*NodeData),
		LastUpdate: time.Now(),
	}

	for _, nodeConfig := range config.NodeConfigs {
		nodeData := &NodeData{
			Config:     nodeConfig,
			LastUpdate: time.Now(),
			DataSource: createDataSource(nodeConfig.DataSource),
		}
		dataModel.Nodes[nodeConfig.SlaveID] = nodeData
	}

	fmt.Printf("✅ 数据模型初始化完成，包含 %d 个节点\n", len(dataModel.Nodes))
	return dataModel
}

// createDataSource 创建数据源
func createDataSource(sourceType string) DataSource {
	// 根据类型创建不同的数据源模拟器
	switch sourceType {
	case "plc_simulator":
		return &PLCSimulator{}
	case "sensor_simulator":
		return &SensorSimulator{}
	case "motor_simulator":
		return &MotorSimulator{}
	default:
		return &GenericSimulator{}
	}
}

// PLCSimulator PLC模拟器
type PLCSimulator struct{}

func (p *PLCSimulator) ReadSensorData() ([]uint16, error) {
	// 模拟PLC传感器数据
	data := make([]uint16, 10)
	for i := range data {
		data[i] = uint16(1000 + i*100 + time.Now().Unix()%100)
	}
	return data, nil
}

func (p *PLCSimulator) ReadStatusData() ([]bool, error) {
	// 模拟PLC状态数据
	status := make([]bool, 10)
	for i := range status {
		status[i] = (time.Now().Unix()+int64(i))%2 == 0
	}
	return status, nil
}

func (p *PLCSimulator) WriteControlData(data []uint16) error {
	// 模拟PLC控制数据写入
	return nil
}

func (p *PLCSimulator) WriteCommandData(data []bool) error {
	// 模拟PLC命令数据写入
	return nil
}

// SensorSimulator 传感器模拟器
type SensorSimulator struct{}

func (s *SensorSimulator) ReadSensorData() ([]uint16, error) {
	// 模拟传感器数据，带有随机变化
	data := make([]uint16, 8)
	base := time.Now().Unix()
	for i := range data {
		data[i] = uint16(2000 + i*50 + base%50)
	}
	return data, nil
}

func (s *SensorSimulator) ReadStatusData() ([]bool, error) {
	// 模拟传感器状态
	status := make([]bool, 8)
	for i := range status {
		status[i] = (time.Now().Unix()+int64(i*2))%3 != 0
	}
	return status, nil
}

func (s *SensorSimulator) WriteControlData(data []uint16) error {
	return nil
}

func (s *SensorSimulator) WriteCommandData(data []bool) error {
	return nil
}

// MotorSimulator 电机模拟器
type MotorSimulator struct{}

func (m *MotorSimulator) ReadSensorData() ([]uint16, error) {
	// 模拟电机参数数据
	data := make([]uint16, 6)
	base := time.Now().Unix()
	data[0] = uint16(1500 + base%200) // 转速
	data[1] = uint16(300 + base%100)  // 电流
	data[2] = uint16(400 + base%50)   // 电压
	data[3] = uint16(50 + base%30)    // 温度
	data[4] = uint16(85 + base%15)    // 效率
	data[5] = uint16(10 + base%20)    // 振动
	return data, nil
}

func (m *MotorSimulator) ReadStatusData() ([]bool, error) {
	// 模拟电机状态
	status := make([]bool, 6)
	status[0] = true                        // 运行状态
	status[1] = (time.Now().Unix())%10 < 8  // 正常状态
	status[2] = (time.Now().Unix())%20 < 19 // 无故障
	status[3] = (time.Now().Unix())%5 < 3   // 维护状态
	status[4] = (time.Now().Unix())%15 < 12 // 效率状态
	status[5] = (time.Now().Unix())%25 < 20 // 温度状态
	return status, nil
}

func (m *MotorSimulator) WriteControlData(data []uint16) error {
	return nil
}

func (m *MotorSimulator) WriteCommandData(data []bool) error {
	return nil
}

// GenericSimulator 通用模拟器
type GenericSimulator struct{}

func (g *GenericSimulator) ReadSensorData() ([]uint16, error) {
	data := make([]uint16, 5)
	for i := range data {
		data[i] = uint16(1000 + i*100 + time.Now().Unix()%100)
	}
	return data, nil
}

func (g *GenericSimulator) ReadStatusData() ([]bool, error) {
	status := make([]bool, 5)
	for i := range status {
		status[i] = (time.Now().Unix()+int64(i))%2 == 0
	}
	return status, nil
}

func (g *GenericSimulator) WriteControlData(data []uint16) error {
	return nil
}

func (g *GenericSimulator) WriteCommandData(data []bool) error {
	return nil
}
